#pragma once

#include <cByteStream.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock.h>
#include <string>

#pragma comment(lib, "ws2_32.lib")
namespace mdk
{
    using namespace std;

    /*
        HTTPRequest: Structure that returns the HTTP headers and message
        from the request
    */
    class HTTPRequest
    {
    public:
        LPSTR headerSend;    // Pointer to HTTP header Send
        LPSTR headerReceive; // Pointer to HTTP headers Receive
        LPSTR message;       // Pointer to the HTTP message
        long messageLength;  // Length of the message
        HTTPRequest()
        {
            headerSend = NULL;
            headerReceive = NULL;
            message = NULL;
            messageLength = 0;
        }
        ~HTTPRequest()
        {
            if (headerSend)
                free(headerSend);
            if (headerReceive)
                free(headerReceive);
            if (message)
                free(message);
            messageLength = 0;
        }
    };
    using RequestBody = mdk::CByteBuffer;

    /*
        MemBuffer:  Structure used to implement a memory buffer, which is a
                    buffer of memory that will grow to hold variable sized
                    parts of the HTTP message.
    */
    typedef struct
    {
        unsigned char *buffer;
        unsigned char *position;
        size_t size;
    } MemBuffer;

    class Request
    {
    public:
        Request();
        virtual ~Request();

    private:
        void MemBufferCreate(MemBuffer *b);
        void MemBufferGrow(MemBuffer *b);
        void MemBufferAddByte(MemBuffer *b, unsigned char byt);
        void MemBufferAddBuffer(MemBuffer *b, unsigned char *buffer, size_t size);
        DWORD GetHostAddress(LPCSTR host);
        void SendString(SOCKET sock, LPCSTR str);
        BOOL ValidHostChar(char ch);
        void ParseURL(string url, LPSTR protocol, int lprotocol, LPSTR host,
                      int lhost, LPSTR request, int lrequest, int *port);

    public:
        int SendHTTP(string url, LPCSTR headerReceive, BYTE *post,
                     DWORD postLength, HTTPRequest *req);
        int SendRequest(bool IsPost, string url, RequestBody &bodyData,
                        string &pszHeaderReceive, string &pszMessage);
    };
}